package 事务专题;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

/**
 * 不可重复读案例
 * @author idea
 * @date 2019/7/2
 * @Version V1.0
 */
public class RepeatReadDemo {

    public static final String READ_SQL = "SELECT * FROM money";
    public static final String WRITE_SQL = "INSERT INTO `money` (`id`, `money`) VALUES ('3', '350')";

    public Object lock = new Object();


    /**
     * 可重复读模拟  （如果当前事务进行读取，但是没有提交事务，那么无法读取其他事务里面的信息（即使已经提交的信息））
     */
    public  void repeatRead() {
        Thread writeThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try (Connection conn = JdbcUtil.getConnection();) {
                    //堵塞等待唤醒
                    synchronized (lock) {
                        lock.wait();
                    }
                    conn.setAutoCommit(true);
                    PreparedStatement ps = conn.prepareStatement(WRITE_SQL);
                    ps.executeUpdate();
                    System.out.println("执行写取数据操作----");
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        Thread readThread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Connection readConn = JdbcUtil.getConnection();
                    readConn.setAutoCommit(false);
                    readConn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
                    PreparedStatement readPs = readConn.prepareStatement(READ_SQL);
                    ResultSet rs = readPs.executeQuery();
                    System.out.println("执行读取数据操作1----");
                    List list = JdbcUtil.convertList(rs);
                    for (Object obj : list) {
                        System.out.println(obj);
                    }

                    synchronized (lock){
                        lock.notify();
                    }

                    Thread.sleep(1000);
                    ResultSet rs2 = readPs.executeQuery();
                    System.out.println("执行读取数据操作2----");
                    List list2 = JdbcUtil.convertList(rs2);
                    for (Object obj : list2) {
                        System.out.println(obj);
                    }
                    readConn.commit();
                    readConn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        writeThread.start();
        readThread.start();
    }

    public static void main(String[] args) {
        RepeatReadDemo repeatReadDemo=new RepeatReadDemo();
        repeatReadDemo.repeatRead();
    }

}
